package com.hakim.wfb.customer.service.biz;

import com.hakim.wfb.bean.ConsumeRecord;
import com.hakim.wfb.bean.ConsumeRule;
import com.hakim.wfb.bean.CreditPoint;
import com.hakim.wfb.bean.Dictionary;
import com.hakim.wfb.bean.PointOrder;
import com.hakim.wfb.bean.User;
import com.hakim.wfb.biz.ConsumeRecordBiz;
import com.hakim.wfb.biz.ConsumeRuleBiz;
import com.hakim.wfb.biz.CreditPointBiz;
import com.hakim.wfb.biz.PointOrderBiz;
import com.hakim.wfb.biz.UserBiz;
import com.hakim.wfb.common.enums.PointTypeEnum;
import com.hakim.wfb.common.enums.TransTypeEnum;
import com.hakim.wfb.common.enums.UserActiveTypeEnum;
import com.hakim.wfb.common.enums.UserInvestStatusEnum;
import com.hakim.wfb.common.enums.UserLevelEnum;
import com.hakim.wfb.common.serial.SerialNoGenerator;
import com.hakim.wfb.common.serial.UUIDGenerator;
import com.hakim.wfb.common.util.DateUtils;
import com.hakim.wfb.customer.constants.BizConst;
import com.hakim.wfb.customer.enums.ErrorCodeEnum;
import com.hakim.wfb.customer.params.trans.AddConsumeRecordParameter;
import com.hakim.wfb.customer.params.trans.GetConsumeRecordParameter;
import com.hakim.wfb.customer.params.trans.PlaceOrderParameter;
import com.hakim.wfb.dao.DictionaryDao;
import com.hkfs.fundamental.api.data.ResultEx;
import com.hkfs.fundamental.exception.HkfsBizException;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by Administrator on 2017/7/3.
 */
@Service("transactionBizService")
public class TransactionBizService {

    private static final String DEFAULT_ORG_SPILT = "_";//组织机构分隔符

    private final Logger logger = LoggerFactory.getLogger(TransactionBizService.class);

    @Autowired
    private UserBiz userBiz;

    @Autowired
    private CreditPointBiz creditPointBiz;

    @Autowired
    private ConsumeRecordBiz consumeRecordBiz;

    @Autowired
    private ConsumeRuleBiz consumeRuleBiz;

    @Autowired
    private PointOrderBiz pointOrderBiz;

    @Autowired
    private DictionaryDao dictionaryDao;

    private ConsumeRule currentConsumeRule;

    private User currentUser;

    private CreditPoint currentCreditPoint;

    private PlaceOrderParameter placeOrderParameter;

    /**
     * 订单号
     */
    private String orderNo;

    /**
     * 消费币
     */
    private double tax;

    //当前投资者组织机构级数
    private int ug = 0;

    /**
     * 当前用户的所有上级用户
     */
    private List<User> allUpUserList = new LinkedList<>();

    /**
     * 当前用户的所有上级用户的积分信息
     */
    private List<CreditPoint> allUpCreditPointList = new LinkedList<>();

    private Date now = new Date();

    private String nowStr = DateUtils.dateToStrLong(now) + " ";

    /**
     * @param parameter
     * @return
     */
    @Transactional
    public ResultEx placeOrder(PlaceOrderParameter parameter) {

        ResultEx resultEx = new ResultEx();
        now = new Date();
        nowStr = DateUtils.dateToStrLong(now) + " ";

        this.placeOrderParameter = parameter;
        if (parameter.getInvestPointAmount() <= 0 ||
                (parameter.getRepeatPoint() + parameter.getOriginalPoint() != parameter
                        .getInvestPointAmount()) ||
                (parameter.getRepeatPoint() <= 0 && parameter.getOriginalPoint() <= 0)) {
            logger.warn(nowStr + "投资额度错误");

            resultEx.setRetCode(ErrorCodeEnum.INVALID_INVEST_AMOUNT_ERROR.getCode());
            resultEx.setRetMsg(ErrorCodeEnum.INVALID_INVEST_AMOUNT_ERROR.getMessage());
            return resultEx.makeFailedResult();
        }
        if ("2".equals(parameter.getRuleId())) {
            Dictionary dictionary = dictionaryDao.getById("2");
            if (dictionary == null || dictionary.getDdValue().isEmpty() || dictionary.getDdValue()
                    .equalsIgnoreCase("false")) {
                logger.warn(nowStr + "月消模式暂不开放");
                return resultEx.makeFailedResult("月消模式暂不开放");
            }
        }

        currentUser = userBiz.getUser(parameter.getUserId());
        if (currentUser == null) {
            logger.warn(nowStr + "用户id：" + parameter.getUserId() + ",无此用户信息");
            resultEx.setRetCode(ErrorCodeEnum.USER_NOT_EXIST_ERROR.getCode());
            resultEx.setRetMsg(ErrorCodeEnum.USER_NOT_EXIST_ERROR.getMessage());
            return resultEx.makeFailedResult();
        }

        if (!parameter.getPayPassword().equals(currentUser.getUserTradePwd())) {
            logger.warn(nowStr + "用户id：" + parameter.getUserId() + ",支付密码错误");
            resultEx.setRetCode(ErrorCodeEnum.USER_TRADE_PASSWORD_ERROR.getCode());
            resultEx.setRetMsg(ErrorCodeEnum.USER_TRADE_PASSWORD_ERROR.getMessage());
            return resultEx.makeFailedResult();
        }

        currentCreditPoint = creditPointBiz.getCreditPointById(parameter.getUserId());
        if (currentCreditPoint == null) {
            logger.warn(nowStr + "用户id：" + parameter.getUserId() + ",无此用户积分信息");
            resultEx.setRetCode(ErrorCodeEnum.USER_CREDIT_POINT_NOT_EXIST_ERROR.getCode());
            resultEx.setRetMsg(ErrorCodeEnum.USER_CREDIT_POINT_NOT_EXIST_ERROR.getMessage());
            return resultEx.makeFailedResult();
        }
        currentConsumeRule = consumeRuleBiz.getConsumeRule(parameter.getRuleId());
        if (currentConsumeRule == null) {
            logger.warn(nowStr + "没有找到此消费规则");
            return resultEx.makeFailedResult("没有找到此消费规则！");
        }

        String[] arr = currentUser.getUserOrg().split(DEFAULT_ORG_SPILT);
        ug = arr.length;//获取当前组织机构代数

        GetConsumeRecordParameter getConsumeRecordParameter = new GetConsumeRecordParameter();
        getConsumeRecordParameter.setUserId(currentUser.getTid());
        int runningCount = consumeRecordBiz.countInvestTimesByUserId(currentUser.getTid());
        if (runningCount > 0) {
            logger.warn(nowStr + "存在未完成的消费");
            return resultEx.makeFailedResult("存在未完成的消费！");
        }

        if (currentCreditPoint.getCpInRepeatPoint() + currentCreditPoint.getCpCapitalPoint()
                > 20000) {
            logger.warn(nowStr + "投资额度超过20000");
            return resultEx.makeFailedResult("投资额度最高不能超过20000！");
        }

        if (parameter.getOriginalPoint() > 0) {
            if (parameter.getOriginalPoint() > currentCreditPoint.getCpOriginalPoint()) {
                return resultEx.makeFailedResult("原始积分不足！");
            } else {
                currentCreditPoint.setCpOriginalPoint(
                        currentCreditPoint.getCpOriginalPoint() - parameter.getOriginalPoint());
                currentCreditPoint.setCpCapitalPoint(
                        currentCreditPoint.getCpCapitalPoint() + parameter.getOriginalPoint());
            }
        }

        if (parameter.getRepeatPoint() > 0) {
            if (parameter.getRepeatPoint() > currentCreditPoint.getCpRepeatPoint()) {
                return resultEx.makeFailedResult("复投积分不足！");
            } else {
                currentCreditPoint.setCpRepeatPoint(
                        currentCreditPoint.getCpRepeatPoint() - parameter.getRepeatPoint());
                //在投复投
                currentCreditPoint.setCpInRepeatPoint(
                        currentCreditPoint.getCpInRepeatPoint() + parameter.getRepeatPoint());
            }
        }

        //计算消费币
        tax = currentConsumeRule.getCrTax() / 100 * parameter.getInvestPointAmount();
        if (currentCreditPoint.getCpCustPoint() >= tax) {
            currentCreditPoint.setCpCustPoint(currentCreditPoint.getCpCustPoint() - tax);
        } else {
            return resultEx.makeFailedResult("消费币不足，请充值！");
        }

        //增加个人业绩
        //个人业绩为实际投资中的金额,投资到期需要扣除
        currentCreditPoint.setCpPerformancePoint(
                currentCreditPoint.getCpPerformancePoint() + parameter.getInvestPointAmount());

        try {

            //设置投资中
            currentUser.setUserInvesting(UserInvestStatusEnum.INVESTING.getValue());
            userBiz.Update(currentUser);
            orderNo = SerialNoGenerator.getInvestmentOrderNo(currentUser.getUserPhone());

            //增加投资记录
            AddConsumeRecordParameter addConsumeRecordParameter = new AddConsumeRecordParameter();
            addConsumeRecordParameter.setOrderno(orderNo);
            addConsumeRecordParameter.setOriginalPoint(parameter.getOriginalPoint());
            addConsumeRecordParameter.setRepeatPoint(parameter.getRepeatPoint());
            addConsumeRecordParameter.setInvestTime(now);
            addConsumeRecordParameter.setUserId(currentUser.getTid());
            addConsumeRecordParameter.setRewardRemainCount(currentConsumeRule.getCrDays());
            addConsumeRecordParameter
                    .setRewardTime(DateUtils.getNextDayTime(now, currentConsumeRule.getCrDays()));
            addConsumeRecordParameter.setCustRule(parameter.getRuleId());
            addConsumeRecord(addConsumeRecordParameter);

            //增加投资划拨表记录
            operInvestmentOrder(parameter);

            //增加消费币划拨表记录
            AddConsumePointOrder();

            allUpUserList.add(currentUser);
            allUpCreditPointList.add(currentCreditPoint);

            //递归处理团队业绩
            processUpTeamPerformance(currentUser);

            //从下到上计算用户等级
            if (parameter.getOriginalPoint() > 0) {

                for (User u : allUpUserList) {
                    processUpUserLevel(u);
                }
            }
            //从上到上计算业绩奖励,上下同级别只有最下能拿到业绩奖励
            if (parameter.getOriginalPoint() > 0) {

                logger.info(String.valueOf(allUpUserList.size()));
                //按照用户推荐层级排序
//                List<User> sortedDownUserList = allUpUserList.stream()
//                        .sorted(Comparator.comparing(User::getUserOrg))
//                        .collect(Collectors.toList());
//                for (User u : sortedDownUserList) {
//                    //计算业绩奖励,原始积分部分才计算
//                    processPerformanceAward(u);
//                }
            }
            //积分总表变动
            currentCreditPoint
                    .setCpPerformanceCount(currentCreditPoint.getCpPerformanceCount() + 1);
            int updateCount = creditPointBiz.update(currentCreditPoint);
            if (updateCount <= 0) {
                throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(),
                        ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
            }
            return resultEx.makeSuccessResult();
        } catch (Exception e) {
            logger.info(e.getMessage());
            return resultEx.makeFailedResult("系统错误！");
        }
    }

    /**
     * 增加投资记录
     */
    private void addConsumeRecord(AddConsumeRecordParameter orderParameter) {

        if (orderParameter.getOriginalPoint() > 0) {
            ConsumeRecord consumeRecordOriginal = new ConsumeRecord();
            consumeRecordOriginal.setTid(UUIDGenerator.getUUID());
            consumeRecordOriginal.setCrOrderno(orderParameter.getOrderno());
            consumeRecordOriginal.setCrUser(orderParameter.getUserId());
            consumeRecordOriginal.setCrInvestTime(orderParameter.getInvestTime());
            consumeRecordOriginal.setCrCustRule(orderParameter.getCustRule());
            consumeRecordOriginal.setCrCustPoint(orderParameter.getOriginalPoint());
            consumeRecordOriginal.setCrPointType(PointTypeEnum.ORIGINAL_POINT.getValue());
            consumeRecordOriginal.setCrRewardTime(orderParameter.getRewardTime());
            consumeRecordOriginal.setCrRewardRemainCount(orderParameter.getRewardRemainCount());
            consumeRecordBiz.add(consumeRecordOriginal);
            logger.info(nowStr + "增加投资消费记录,用户订单号：" + orderNo);
        }
        if (orderParameter.getRepeatPoint() > 0) {
            ConsumeRecord consumeRecordRepeat = new ConsumeRecord();
            consumeRecordRepeat.setTid(UUIDGenerator.getUUID());
            consumeRecordRepeat.setCrOrderno(orderParameter.getOrderno());
            consumeRecordRepeat.setCrUser(orderParameter.getUserId());
            consumeRecordRepeat.setCrInvestTime(orderParameter.getInvestTime());
            consumeRecordRepeat.setCrCustRule(orderParameter.getCustRule());
            consumeRecordRepeat.setCrCustPoint(orderParameter.getRepeatPoint());
            consumeRecordRepeat.setCrPointType(PointTypeEnum.REPEAT_POINT.getValue());
            consumeRecordRepeat.setCrRewardTime(orderParameter.getRewardTime());
            consumeRecordRepeat.setCrRewardRemainCount(orderParameter.getRewardRemainCount());
            consumeRecordBiz.add(consumeRecordRepeat);
            logger.info(nowStr + "增加投资消费记录,用户订单号：" + orderNo);
        }
    }

    /**
     * 创建投资积分变动明细
     */
    private List<PointOrder> createInvestmentOrder(PlaceOrderParameter parameter) {

        List<PointOrder> pointOrders = new LinkedList<>();
        //原始积分投资部分
        if (placeOrderParameter.getOriginalPoint() > 0) {

            //用户资本积分增加
            PointOrder plusPointOrderOriginal = new PointOrder();
            plusPointOrderOriginal.setTid(UUIDGenerator.getUUID());
            plusPointOrderOriginal.setPoAmount(currentCreditPoint.getCpCapitalPoint());
            plusPointOrderOriginal.setPoCreateDate(DateUtils.getNow());
            plusPointOrderOriginal.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式，" + "原始积分投资："
                            + parameter.getOriginalPoint());
            plusPointOrderOriginal.setPoFromUser(currentUser.getTid());
            plusPointOrderOriginal.setPoOrderno(orderNo);
            plusPointOrderOriginal.setPoPointType(PointTypeEnum.CAPITAL_POINT.getValue());
            plusPointOrderOriginal.setPoToUser(currentUser.getTid());
            plusPointOrderOriginal.setPoTransPoint(parameter.getOriginalPoint());
            plusPointOrderOriginal.setPoType(TransTypeEnum.INVESTMENT.getValue());

            pointOrders.add(plusPointOrderOriginal);

            //用户原始积分减少
            PointOrder minusPointOrderOriginal = new PointOrder();
            minusPointOrderOriginal.setTid(UUIDGenerator.getUUID());
            minusPointOrderOriginal.setPoAmount(currentCreditPoint.getCpOriginalPoint());
            minusPointOrderOriginal.setPoCreateDate(DateUtils.getNow());
            minusPointOrderOriginal.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式：" + "原始积分投资：-"
                            + parameter.getOriginalPoint());
            minusPointOrderOriginal.setPoFromUser(currentUser.getTid());
            minusPointOrderOriginal.setPoOrderno(orderNo);
            minusPointOrderOriginal.setPoPointType(PointTypeEnum.ORIGINAL_POINT.getValue());
            minusPointOrderOriginal.setPoToUser(currentUser.getTid());
            minusPointOrderOriginal.setPoTransPoint(parameter.getOriginalPoint() * -1);
            minusPointOrderOriginal.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrders.add(minusPointOrderOriginal);

            logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，原始积分投资"
                    + "积分变动订单号！【" + orderNo + "】");
        }
        //复投积分投资部分
        if (placeOrderParameter.getRepeatPoint() > 0) {

            //用户在投复投增加
            PointOrder plusPointOrderRepeat = new PointOrder();
            plusPointOrderRepeat.setTid(UUIDGenerator.getUUID());
            plusPointOrderRepeat.setPoCreateDate(DateUtils.getNow());
            plusPointOrderRepeat.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式，" + "复投积分投资："
                            + parameter.getRepeatPoint());
            plusPointOrderRepeat.setPoFromUser(currentUser.getTid());
            plusPointOrderRepeat.setPoToUser(currentUser.getTid());
            plusPointOrderRepeat.setPoOrderno(orderNo);
            plusPointOrderRepeat.setPoPointType(PointTypeEnum.IN_REPEAT_POINT.getValue());
            plusPointOrderRepeat.setPoTransPoint(parameter.getRepeatPoint());
            plusPointOrderRepeat.setPoAmount(currentCreditPoint.getCpInRepeatPoint());
            plusPointOrderRepeat.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrders.add(plusPointOrderRepeat);

            //用户复投积分减少
            PointOrder minusPointOrderRepeat = new PointOrder();
            minusPointOrderRepeat.setTid(UUIDGenerator.getUUID());
            minusPointOrderRepeat.setPoAmount(currentCreditPoint.getCpRepeatPoint());
            minusPointOrderRepeat.setPoCreateDate(DateUtils.getNow());
            minusPointOrderRepeat.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式：" + "复投积分投资：-"
                            + parameter.getRepeatPoint());
            minusPointOrderRepeat.setPoFromUser(currentUser.getTid());
            minusPointOrderRepeat.setPoOrderno(orderNo);
            minusPointOrderRepeat.setPoPointType(PointTypeEnum.REPEAT_POINT.getValue());
            minusPointOrderRepeat.setPoToUser(currentUser.getTid());
            minusPointOrderRepeat.setPoTransPoint(parameter.getRepeatPoint() * -1);
            minusPointOrderRepeat.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrders.add(minusPointOrderRepeat);

            logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，复投积分投资"
                    + "积分变动订单号！【" + orderNo + "】");
        }

        return pointOrders;
    }

    /**
     * 增加划拨表消费币记录
     */
    private List<PointOrder> CreateConsumePointOrder() {

        List<PointOrder> pointOrders = new LinkedList<>();
        //系统消费积分增加
        PointOrder plusPointOrder = new PointOrder();
        plusPointOrder.setTid(UUIDGenerator.getUUID());
        plusPointOrder.setPoAmount(0);
        plusPointOrder.setPoCreateDate(DateUtils.getNow());
        plusPointOrder.setPoDescription(
                Integer.toString(currentConsumeRule.getCrDays()) + "日模式，系统收到" + currentUser
                        .getUserCode() + "消费币：" + tax);
        plusPointOrder.setPoFromUser(currentUser.getTid());
        plusPointOrder.setPoOrderno(orderNo);
        plusPointOrder.setPoPointType(PointTypeEnum.CUST_POINT.getValue());
        plusPointOrder.setPoToUser("0");
        plusPointOrder.setPoTransPoint(tax);
        plusPointOrder.setPoType(TransTypeEnum.INVESTMENT.getValue());
        pointOrders.add(plusPointOrder);

        //系统消费积分减少
        PointOrder minusPointOrder = new PointOrder();
        minusPointOrder.setTid(UUIDGenerator.getUUID());
        minusPointOrder.setPoAmount(currentCreditPoint.getCpCustPoint());
        minusPointOrder.setPoCreateDate(DateUtils.getNow());
        minusPointOrder.setPoDescription(
                Integer.toString(currentConsumeRule.getCrDays()) + "日模式，支出消费币：" + tax);
        minusPointOrder.setPoFromUser("0");
        minusPointOrder.setPoOrderno(orderNo);
        minusPointOrder.setPoPointType(PointTypeEnum.CUST_POINT.getValue());
        minusPointOrder.setPoToUser(currentUser.getTid());
        minusPointOrder.setPoTransPoint(tax * -1);
        minusPointOrder.setPoType(TransTypeEnum.INVESTMENT.getValue());
        pointOrders.add(minusPointOrder);

        logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，消费币变动订单号！【"
                + orderNo + "】");

        return pointOrders;
    }

    /**
     * 增加投资积分变动明细
     */
    private void operInvestmentOrder(PlaceOrderParameter parameter) {
        //原始积分投资部分
        if (placeOrderParameter.getOriginalPoint() > 0) {

            //用户资本积分增加
            PointOrder plusPointOrderOriginal = new PointOrder();
            plusPointOrderOriginal.setTid(UUIDGenerator.getUUID());
            plusPointOrderOriginal.setPoAmount(currentCreditPoint.getCpCapitalPoint());
            plusPointOrderOriginal.setPoCreateDate(DateUtils.getNow());
            plusPointOrderOriginal.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式，" + "原始积分投资："
                            + parameter.getOriginalPoint());
            plusPointOrderOriginal.setPoFromUser(currentUser.getTid());
            plusPointOrderOriginal.setPoOrderno(orderNo);
            plusPointOrderOriginal.setPoPointType(PointTypeEnum.CAPITAL_POINT.getValue());
            plusPointOrderOriginal.setPoToUser(currentUser.getTid());
            plusPointOrderOriginal.setPoTransPoint(parameter.getOriginalPoint());
            plusPointOrderOriginal.setPoType(TransTypeEnum.INVESTMENT.getValue());

            pointOrderBiz.add(plusPointOrderOriginal);

            //用户原始积分减少
            PointOrder minusPointOrderOriginal = new PointOrder();
            minusPointOrderOriginal.setTid(UUIDGenerator.getUUID());
            minusPointOrderOriginal.setPoAmount(currentCreditPoint.getCpOriginalPoint());
            minusPointOrderOriginal.setPoCreateDate(DateUtils.getNow());
            minusPointOrderOriginal.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式：" + "原始积分投资：-"
                            + parameter.getOriginalPoint());
            minusPointOrderOriginal.setPoFromUser(currentUser.getTid());
            minusPointOrderOriginal.setPoOrderno(orderNo);
            minusPointOrderOriginal.setPoPointType(PointTypeEnum.ORIGINAL_POINT.getValue());
            minusPointOrderOriginal.setPoToUser(currentUser.getTid());
            minusPointOrderOriginal.setPoTransPoint(parameter.getOriginalPoint() * -1);
            minusPointOrderOriginal.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrderBiz.add(minusPointOrderOriginal);

            logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，原始积分投资"
                    + "积分变动订单号！【" + orderNo + "】");
        }
        //复投积分投资部分
        if (placeOrderParameter.getRepeatPoint() > 0) {

            //用户在投复投增加
            PointOrder plusPointOrderRepeat = new PointOrder();
            plusPointOrderRepeat.setTid(UUIDGenerator.getUUID());
            plusPointOrderRepeat.setPoCreateDate(DateUtils.getNow());
            plusPointOrderRepeat.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式，" + "复投积分投资："
                            + parameter.getRepeatPoint());
            plusPointOrderRepeat.setPoFromUser(currentUser.getTid());
            plusPointOrderRepeat.setPoToUser(currentUser.getTid());
            plusPointOrderRepeat.setPoOrderno(orderNo);
            plusPointOrderRepeat.setPoPointType(PointTypeEnum.IN_REPEAT_POINT.getValue());
            plusPointOrderRepeat.setPoTransPoint(parameter.getRepeatPoint());
            plusPointOrderRepeat.setPoAmount(currentCreditPoint.getCpInRepeatPoint());
            plusPointOrderRepeat.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrderBiz.add(plusPointOrderRepeat);

            //用户复投积分减少
            PointOrder minusPointOrderRepeat = new PointOrder();
            minusPointOrderRepeat.setTid(UUIDGenerator.getUUID());
            minusPointOrderRepeat.setPoAmount(currentCreditPoint.getCpRepeatPoint());
            minusPointOrderRepeat.setPoCreateDate(DateUtils.getNow());
            minusPointOrderRepeat.setPoDescription(
                    Integer.toString(currentConsumeRule.getCrDays()) + "日模式：" + "复投积分投资：-"
                            + parameter.getRepeatPoint());
            minusPointOrderRepeat.setPoFromUser(currentUser.getTid());
            minusPointOrderRepeat.setPoOrderno(orderNo);
            minusPointOrderRepeat.setPoPointType(PointTypeEnum.REPEAT_POINT.getValue());
            minusPointOrderRepeat.setPoToUser(currentUser.getTid());
            minusPointOrderRepeat.setPoTransPoint(parameter.getRepeatPoint() * -1);
            minusPointOrderRepeat.setPoType(TransTypeEnum.INVESTMENT.getValue());
            pointOrderBiz.add(minusPointOrderRepeat);

            logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，复投积分投资"
                    + "积分变动订单号！【" + orderNo + "】");
        }
    }

    /**
     * 增加划拨表消费币记录
     */
    private void AddConsumePointOrder() {

        //系统消费积分增加
        PointOrder plusPointOrder = new PointOrder();
        plusPointOrder.setTid(UUIDGenerator.getUUID());
        plusPointOrder.setPoAmount(0);
        plusPointOrder.setPoCreateDate(DateUtils.getNow());
        plusPointOrder.setPoDescription(
                Integer.toString(currentConsumeRule.getCrDays()) + "日模式，系统收到" + currentUser
                        .getUserCode() + "消费币：" + tax);
        plusPointOrder.setPoFromUser(currentUser.getTid());
        plusPointOrder.setPoOrderno(orderNo);
        plusPointOrder.setPoPointType(PointTypeEnum.CUST_POINT.getValue());
        plusPointOrder.setPoToUser("0");
        plusPointOrder.setPoTransPoint(tax);
        plusPointOrder.setPoType(TransTypeEnum.INVESTMENT.getValue());
        pointOrderBiz.add(plusPointOrder);

        //系统消费积分减少
        PointOrder minusPointOrder = new PointOrder();
        minusPointOrder.setTid(UUIDGenerator.getUUID());
        minusPointOrder.setPoAmount(currentCreditPoint.getCpCustPoint());
        minusPointOrder.setPoCreateDate(DateUtils.getNow());
        minusPointOrder.setPoDescription(
                Integer.toString(currentConsumeRule.getCrDays()) + "日模式，支出消费币：" + tax);
        minusPointOrder.setPoFromUser("0");
        minusPointOrder.setPoOrderno(orderNo);
        minusPointOrder.setPoPointType(PointTypeEnum.CUST_POINT.getValue());
        minusPointOrder.setPoToUser(currentUser.getTid());
        minusPointOrder.setPoTransPoint(tax * -1);
        minusPointOrder.setPoType(TransTypeEnum.INVESTMENT.getValue());
        pointOrderBiz.add(minusPointOrder);

        logger.info(nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，消费币变动订单号！【"
                + orderNo + "】");
    }

    /**
     * 所有上线的积分计算
     */
    private void processUpTeamPerformance(User curUser) throws HkfsBizException {

        if (curUser == null || StringUtils.isBlank(curUser.getUserParent()) || curUser
                .getUserParent().equals("0")) {
            return;
        }

        //获取上一级
        User upUser = userBiz.getUser(curUser.getUserParent());
        if (upUser == null) {
            return;
        }
        CreditPoint upCreditPoint = creditPointBiz.getCreditPoint(upUser.getTid());
        if (upCreditPoint == null) {
            return;
        }
        //团队投资笔数
        upCreditPoint.setCpTeamCount(upCreditPoint.getCpTeamCount() + 1);

        allUpUserList.add(upUser);
        allUpCreditPointList.add(upCreditPoint);

        String[] arrCur = upUser.getUserOrg().split(DEFAULT_ORG_SPILT);
        int upUg = arrCur.length;

        if (upUser.getUserActStatus() == UserActiveTypeEnum.ACTIVED.getValue()) {
            double ratePoint = 0;
            if (upCreditPoint.getCpCapitalPoint() + upCreditPoint.getCpInRepeatPoint()
                    > placeOrderParameter.getInvestPointAmount())//1:1烧伤判断
            {
                ratePoint = placeOrderParameter.getInvestPointAmount();
            } else {
                ratePoint = upCreditPoint.getCpCapitalPoint() + upCreditPoint.getCpInRepeatPoint();
            }

            //原始投资和复投都算业绩，投资到期业绩减少
            upCreditPoint.setCpTeamPoint(upCreditPoint.getCpTeamPoint() + ratePoint);
            upCreditPoint.setUpdatedTime(now);

            //动态奖金
            double award = 0;
            //代数
            int generation = 0;
            //当前用户的直推有效用户列表
            List<User> lstUserDirect = userBiz.getDirectActivatedUsers(upUser.getTid());
            //当前用户的有效直推数
            int directCount = lstUserDirect.size();
            if (upUg + 1 == ug) {
                //当前用户的直推人
                boolean isExistUser = false;
                for (User u : lstUserDirect) {
                    if (u.getTid().equals(currentUser.getTid())) {
                        isExistUser = true;
                        break;
                    }
                }
                if (isExistUser == false) {
                    directCount++;
                }
            }
            GetConsumeRecordParameter consumeParam = new GetConsumeRecordParameter();
            consumeParam.setUserId(upUser.getTid());
            int runningCount = consumeRecordBiz.getRunningConsumeRecordCount(consumeParam);

            //奖金产生规则：有效直推达到一定人数，用户自身有投资
            if (runningCount > 0) {
                if (currentConsumeRule.getCrDays() == 30) {
                    //月消模式
                    if (upUg + 3 == ug && directCount >= 8) {
                        award = 0.12 * ratePoint;
                        generation = 3;
                    } else if (upUg + 2 == ug && directCount >= 4) {
                        award = 0.1 * ratePoint;
                        generation = 2;
                    } else if (upUg + 1 == ug && directCount >= 2) {
                        award = 0.2 * ratePoint;
                        generation = 1;
                    }
                } else if (currentConsumeRule.getCrDays() == 10) {

                    //期消模式
                    if (upUg + 3 == ug && directCount >= 8) {
                        award = 0.04 * ratePoint;
                        generation = 3;
                    } else if (upUg + 2 == ug && directCount >= 4) {
                        award = 0.03 * ratePoint;
                        generation = 2;
                    } else if (upUg + 1 == ug && directCount >= 2) {
                        award = 0.06 * ratePoint;
                        generation = 1;
                    }
                }
            }

            if (award > 0) {

                //动态奖金
                upCreditPoint.setCpDynamicPoint(upCreditPoint.getCpDynamicPoint() + award);

                //用户为正数，增加业绩奖励
                PointOrder plusPointOrder = new PointOrder();
                plusPointOrder.setTid(UUIDGenerator.getUUID());
                plusPointOrder.setPoAmount(upCreditPoint.getCpDynamicPoint());
                plusPointOrder.setPoCreateDate(DateUtils.getNow());
                plusPointOrder.setPoDescription(
                        currentConsumeRule.getCrDescription() + "投资" + placeOrderParameter
                                .getInvestPointAmount() + "，" + generation + "代奖金，" + award);
                plusPointOrder.setPoFromUser("0");
                plusPointOrder.setPoOrderno(orderNo);
                plusPointOrder.setPoPointType(PointTypeEnum.DYNAMIC_POINT.getValue());
                plusPointOrder.setPoToUser(upUser.getTid());
                plusPointOrder.setPoTransPoint(award);
                plusPointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
                pointOrderBiz.add(plusPointOrder);

                //系统为负数
                PointOrder minusPointOrder = new PointOrder();
                minusPointOrder.setTid(UUIDGenerator.getUUID());
                minusPointOrder.setPoAmount(0);
                minusPointOrder.setPoCreateDate(DateUtils.getNow());
                minusPointOrder.setPoDescription(
                        currentConsumeRule.getCrDescription() + "，投资订单号【" + orderNo + "】" + "推广奖励：-"
                                + award);
                minusPointOrder.setPoFromUser(upUser.getTid());
                minusPointOrder.setPoOrderno(orderNo);
                minusPointOrder.setPoPointType(PointTypeEnum.DYNAMIC_POINT.getValue());
                minusPointOrder.setPoToUser("0");
                minusPointOrder.setPoTransPoint(award * -1);
                minusPointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
                pointOrderBiz.add(minusPointOrder);

                logger.info(
                        nowStr + currentConsumeRule.getCrDescription() + "，投资，" + "推广奖励【" + orderNo
                                + "】" + award);
            }

            logger.info("用户：" + upUser.getUserCode() + "，增加团队业绩：" + ratePoint);
            /**
             * 需要增加团队业绩的积分记录，以后需要加上
             */
            int updateCount = creditPointBiz.update(upCreditPoint);
            if (updateCount <= 0) {
                throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(),
                        ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
            }
        }
        if (upUg == 1) {
            return;
        }
        processUpTeamPerformance(upUser);
    }

    /**
     * 递归处理用户等级
     */
    private void processUpUserLevel(User curUser) throws HkfsBizException {

        if (curUser == currentUser || curUser.getTid() == currentUser.getTid()) {
            return;
        }
        //当前用户有效直推人员
        List<User> listDirectOriginal = userBiz.getDirectActivatedUsers(curUser.getTid());
        if (listDirectOriginal == null || listDirectOriginal.size() <= 0) {
            return;
        }
        ///直推用户,积分信息列表
        Map<User, CreditPoint> myDirectUserCreditPoint = new LinkedHashMap<>();
        //当前用户有效直推人数
        int directCount = listDirectOriginal.size();
        for (User u : listDirectOriginal) {
            if (u.getUserActStatus() == UserActiveTypeEnum.ACTIVED.getValue()) {

                //保存最新的user，allUsers中的为最新内存中为最新
                User existUser = existInAllUsers(u.getTid());
                if (existUser == null) {
                    existUser = userBiz.getUser(u.getTid());
                }
                CreditPoint existCreditPoint = creditPointBiz
                        .getCreditPointById(existUser.getTid());
                myDirectUserCreditPoint.put(existUser, existCreditPoint);
            }
        }
        //判断是否需要修改用户级别
        boolean levelChange = false;
        //伞下总监数
        int myDirectorCount = 0;
        //伞下经理数
        int myManagerCount = 0;
        CreditPoint curCreditPoint = creditPointBiz.getCreditPointById(curUser.getTid());
        if (curCreditPoint == null) {
            return;
        }
        //获取业绩收益率和头衔
        if (directCount >= BizConst.PRESIDENT_LEVEL_DIRECT_COUNT_THRESHOLD) {
            //以下为判断总裁
            for (User u : myDirectUserCreditPoint.keySet()) {
                if (u.getUserLevel() == UserLevelEnum.DIRECTOR.getValue()) {
                    myDirectorCount++;
                }
            }
            if (myDirectorCount >= 2) {

                int teamCount = userBiz
                        .countByUserOrgActivated(curUser.getUserOrg() + DEFAULT_ORG_SPILT);
                if (teamCount >= 2000) {

                    if (curUser.getUserLevel() != UserLevelEnum.PRESIDENT.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.PRESIDENT.getValue());
                        levelChange = true;
                    }
                } else {

                    if (curUser.getUserLevel() != UserLevelEnum.DIRECTOR.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.DIRECTOR.getValue());
                        levelChange = true;
                    }
                }
            } else {

                if (curUser.getUserLevel() != UserLevelEnum.DIRECTOR.getValue()) {
                    curUser.setUserLevel(UserLevelEnum.DIRECTOR.getValue());
                    levelChange = true;
                }
            }

        } else if (directCount >= BizConst.DIRECTOR_LEVEL_DIRECT_COUNT_THRESHOLD) {
            //以下为判断总监
            for (User u : myDirectUserCreditPoint.keySet()) {
                if (u.getUserLevel() == UserLevelEnum.DIRECTOR.getValue()) {
                    myDirectorCount++;
                } else if (u.getUserLevel() == UserLevelEnum.MANAGER.getValue()) {
                    myManagerCount++;
                }
            }
            if (myDirectorCount + myManagerCount >= 2) {
                int teamCount = userBiz
                        .countByUserOrgActivated(curUser.getUserOrg() + DEFAULT_ORG_SPILT);
                if (teamCount >= 800) {
                    //判断是否是总监
                    if (curUser.getUserLevel() != UserLevelEnum.DIRECTOR.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.DIRECTOR.getValue());
                        levelChange = true;
                    }
                } else {
                    if (curUser.getUserLevel() != UserLevelEnum.MANAGER.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.MANAGER.getValue());
                        levelChange = true;
                    }
                }
            } else {
                if (curUser.getUserLevel() != UserLevelEnum.MANAGER.getValue()) {
                    curUser.setUserLevel(UserLevelEnum.MANAGER.getValue());
                    levelChange = true;
                }
            }
        } else if (directCount >= BizConst.MANAGER_LEVEL_DIRECT_COUNT_THRESHOLD) {

            boolean managerLevel = false;
            //按照团队业绩排序
            List<CreditPoint> sortedDirectPoint = myDirectUserCreditPoint.values().stream()
                    .sorted(Comparator.comparing(CreditPoint::getCpTeamPoint).reversed())
                    .collect(Collectors.toList());
            if (sortedDirectPoint.size() >= 15) {
                if (sortedDirectPoint.get(0).getCpTeamPoint() >= 100 * 10000 &&
                        sortedDirectPoint.get(1).getCpTeamPoint() >= 50 * 10000 &&
                        curCreditPoint.getCpTeamPoint() >= 200 * 10000) {
                    managerLevel = true;//判断完最大的是否超过100万，第二是否超过50万,总业绩要达到200万
                }
            }
            if (managerLevel) {
                int teamCount = userBiz
                        .countByUserOrgActivated(curUser.getUserOrg() + DEFAULT_ORG_SPILT);
                if (teamCount >= 200) {//判断是否是经理

                    if (curUser.getUserLevel() != UserLevelEnum.MANAGER.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.MANAGER.getValue());
                        levelChange = true;
                    }
                } else {
                    if (curUser.getUserLevel() != UserLevelEnum.NORMAL_USER.getValue()) {
                        curUser.setUserLevel(UserLevelEnum.NORMAL_USER.getValue());
                        levelChange = true;
                    }
                }
            } else {
                if (curUser.getUserLevel() != UserLevelEnum.NORMAL_USER.getValue()) {
                    curUser.setUserLevel(UserLevelEnum.NORMAL_USER.getValue());
                    levelChange = true;
                }
            }
        } else {
            //余下的均为普通用户
            if (curUser.getUserLevel() != UserLevelEnum.NORMAL_USER.getValue()) {
                curUser.setUserLevel(UserLevelEnum.NORMAL_USER.getValue());
                levelChange = true;
            }
        }
        if (levelChange) {
            userBiz.Update(curUser);
            logger.info(nowStr + "用户等级升级为" + UserLevelEnum.getByValue(curUser.getUserLevel())
                    .getDescription());
        }
    }

    /**
     * 处理经理及及其以上级别业绩奖励
     */
    private void processPerformanceAward(User curUser) throws HkfsBizException {

        if (curUser == currentUser || curUser.getTid() == currentUser.getTid()) {
            return;
        }
        //业绩收益率
        double awardDynamic = 0.0;

        CreditPoint curCreditPoint = creditPointBiz.getCreditPointById(curUser.getTid());
        if (curCreditPoint == null) {
            return;
        }
        User myDirectUser = null;
        if (curUser.getUserLevel() == UserLevelEnum.MANAGER.getValue()) {

            //直线下有同一等级用户
            Optional<User> optional = allUpUserList.stream().
                    filter(x -> x.getUserOrg().startsWith(curUser.getUserOrg() + DEFAULT_ORG_SPILT)
                            && x.getUserLevel().equals(UserLevelEnum.MANAGER.getValue())
                    ).findFirst();
            if (optional.isPresent()) {
                myDirectUser = optional.get();
            }
            if (myDirectUser != null) {
                awardDynamic = 0.0;
            } else {
                awardDynamic = BizConst.MANAGER_PERFORMANCE_AWARD_PERCENT;
            }
        } else if (curUser.getUserLevel() == UserLevelEnum.DIRECTOR.getValue()) {

            //直线下有同一等级用户
            Optional<User> optional = allUpUserList.stream().
                    filter(x -> x.getUserOrg().startsWith(curUser.getUserOrg() + DEFAULT_ORG_SPILT)
                            && x.getUserLevel().equals(UserLevelEnum.DIRECTOR.getValue())
                    ).findFirst();
            if (optional.isPresent()) {
                myDirectUser = optional.get();
            }
            if (myDirectUser != null) {
                awardDynamic = 0.0;
            } else {
                awardDynamic = BizConst.DIRECTOR_PERFORMANCE_AWARD_PERCENT;
            }
        } else if (curUser.getUserLevel() == UserLevelEnum.PRESIDENT.getValue()) {
            //直线下有同一等级用户，则上级用户不拿奖励
            Optional<User> optional = allUpUserList.stream().
                    filter(x -> x.getUserOrg().startsWith(curUser.getUserOrg() + DEFAULT_ORG_SPILT)
                            && x.getUserLevel().equals(UserLevelEnum.PRESIDENT.getValue())
                    ).findFirst();
            if (optional.isPresent()) {
                myDirectUser = optional.get();
            }
            if (myDirectUser != null) {
                awardDynamic = 0.0;
            } else {
                awardDynamic = BizConst.PRESIDENT_PERFORMANCE_AWARD_PERCENT;
            }
        }
        //只有原始积分投资才计算动态奖金
        if (awardDynamic > 0 && placeOrderParameter.getOriginalPoint() > 0) {

            double award = awardDynamic * placeOrderParameter.getOriginalPoint();
            //用户为正数，增加业绩奖励
            PointOrder pointOrder = new PointOrder();
            pointOrder.setTid(UUIDGenerator.getUUID());
            pointOrder.setPoCreateDate(DateUtils.getNow());
            pointOrder.setPoDescription(
                    currentConsumeRule.getCrDescription() + ",投资订单号【" + orderNo + "】"
                            + UserLevelEnum.getByValue(curUser.getUserLevel()).getDescription()
                            + "业绩奖励：" + award);
            pointOrder.setPoFromUser("0");
            pointOrder.setPoOrderno(orderNo);
            pointOrder.setPoPointType(PointTypeEnum.DYNAMIC_POINT.getValue());
            pointOrder.setPoToUser(curUser.getTid());
            pointOrder.setPoTransPoint(award);
            pointOrder.setPoAmount(curCreditPoint.getCpDynamicPoint() + award);
            pointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
            pointOrderBiz.add(pointOrder);

            //系统为负数
            PointOrder reversePointOrder = new PointOrder();
            reversePointOrder.setTid(UUIDGenerator.getUUID());
            reversePointOrder.setPoAmount(0);
            reversePointOrder.setPoCreateDate(DateUtils.getNow());
            reversePointOrder.setPoDescription(
                    currentConsumeRule.getCrDescription() + ",投资订单号【" + orderNo + "】"
                            + UserLevelEnum.getByValue(curUser.getUserLevel()).getDescription()
                            + "业绩奖励：" + award);
            reversePointOrder.setPoFromUser(curUser.getTid());
            reversePointOrder.setPoOrderno(orderNo);
            pointOrder.setPoPointType(PointTypeEnum.DYNAMIC_POINT.getValue());
            reversePointOrder.setPoToUser("0");
            reversePointOrder.setPoTransPoint(award * -1);
            reversePointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
            pointOrderBiz.add(reversePointOrder);

            //动态积分增加
            curCreditPoint.setCpDynamicPoint(curCreditPoint.getCpDynamicPoint() + award);
            int updateCount = creditPointBiz.update(curCreditPoint);
            if (updateCount <= 0) {
                throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(),
                        ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
            }
            logger.info(
                    nowStr + Integer.toString(currentConsumeRule.getCrDays()) + "日模式投资，" + "业绩奖励【"
                            + orderNo + "】" + award);
        }
    }

    private CreditPoint existInAllCreditPoints(String userId) {
        if (allUpCreditPointList == null || allUpCreditPointList.size() <= 0) {
            return null;
        }
        Optional<CreditPoint> optional = allUpCreditPointList.stream()
                .filter(x -> x.getTid().equals(userId)).findFirst();
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }

    private User existInAllUsers(String userId) {
        if (allUpUserList == null || allUpUserList.size() <= 0) {
            return null;
        }
        Optional<User> optional = allUpUserList.stream().filter(x -> x.getTid().equals(userId))
                .findFirst();
        if (optional.isPresent()) {
            return optional.get();
        }
        return null;
    }
}
